package org.piaohao.fast.jfinal;

import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.StrUtil;
import com.google.code.kaptcha.servlet.KaptchaServlet;
import com.jfinal.core.JFinalFilter;
import org.apache.catalina.Context;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.servlets.DefaultServlet;
import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.startup.Tomcat.FixContextListener;
import org.apache.catalina.webresources.StandardRoot;
import org.apache.log4j.Logger;
import org.apache.tomcat.util.descriptor.web.FilterDef;
import org.apache.tomcat.util.descriptor.web.FilterMap;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import java.util.Enumeration;
import java.util.Properties;

/**
 * 启动器
 *
 * @author piaohao
 */
public class Bootstrap {
    private static final Logger log = Logger.getLogger(Bootstrap.class);

    public static void main(String[] args) {
        run(args);
    }

    public static void run(String[] args) {
        DefaultConfig.init();
        String serverType = DefaultConfig.serverType;
        if (StrUtil.isBlank(serverType)) {
            runTomcat(args);
            return;
        }
        if (serverType.equals(Util.ServerType.TOMCAT.name())) {
            runTomcat(args);
        } else if (serverType.equals(Util.ServerType.UNDERTOW.name())) {
//            runUndertow(args);
            System.out.println("undertow is not supported");
        } else {
            runTomcat(args);
        }
    }

    public static void runTomcat(String[] args) {
        long start = System.currentTimeMillis();
        Tomcat tomcat = new Tomcat();
        Integer serverPort = DefaultConfig.serverPort;
        tomcat.setBaseDir(DefaultConfig.tomcatBaseDir);
        tomcat.setPort(serverPort);

        String contextPath = DefaultConfig.contextPath;
        Context context = null;
        context = tomcat.addContext(contextPath, ClassUtil.getClassPath());
        context.setName("jfinal");
        context.addLifecycleListener(new FixContextListener());
        FilterDef filterDef = new FilterDef();
        filterDef.setFilterName("jfinal");
        filterDef.setFilter(new JFinalFilter());
        String configClass = DefaultConfig.configClass;
        if (StrUtil.isBlank(configClass)) {
            log.warn("请配置JFinalConfig");
        }
        filterDef.addInitParameter("configClass", configClass);
        context.addFilterDef(filterDef);
        FilterMap filterMap = new FilterMap();
        filterMap.setFilterName("jfinal");
        filterMap.addURLPattern("/*");
        context.addFilterMap(filterMap);
        StandardRoot standardRoot = new StandardRoot();
        context.setResources(standardRoot);
        tomcat.getHost().addChild(context);
        tomcat.addServlet(contextPath, "defaultServlet", new DefaultServlet());
        context.addServletMappingDecoded("/*", "defaultServlet");
        try {
            if (DefaultConfig.serverinvoke != null) {
                try {
                    Class clazz = Class.forName(DefaultConfig.serverinvoke);
                    IServerInvoke invoker = (IServerInvoke) clazz.newInstance();
                    invoker.invoke(tomcat, context);
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
            }
        } catch (ServletException e) {
            log.error("servlet 配置异常", e);
            System.exit(-1);
        }
        try {
            tomcat.start();
        } catch (LifecycleException e) {
            log.error("tomcat启动失败!", e);
            System.exit(-1);
        }
        log.info(String.format("服务器类型: %s,context-path: %s, port: %d,启动耗时：%d毫秒", "tomcat",
                contextPath, serverPort, (System.currentTimeMillis() - start)));
        tomcat.getServer().await();
    }
}